#include "TLV.h"
int print_train(train_t* ptrain){
    printf("train.type:%d\n",ptrain->type);
    printf("train.length:%d\n",ptrain->length);
    printf("train.value:%s\n",ptrain->value);
    return 0;
}
//接受用户名
int recv_username(int sockfd, char* username) {
    train_t train;
    bzero(&train, sizeof(train));
    int ret_type_count = recv(sockfd, &train.type, sizeof(train.type), MSG_WAITALL);
    int retv_length_count = recv(sockfd, &train.length, sizeof(train.length), MSG_WAITALL);
    recv(sockfd, train.value, train.length, MSG_WAITALL);
    memcpy(username, train.value, train.length);
    if (ret_type_count == 0 || retv_length_count == 0) {
        return 0;
    }
    return train.length;
}
//发送用户名
int send_username(int sockfd, char* username){
    train_t train;
    bzero(&train,sizeof(train));
    train.type = USER_NAME;
    train.length = strlen(username) + 1;
    memcpy(train.value,username,train.length);
    send(sockfd, &train, sizeof(train.type)+sizeof(train.length)+train.length, MSG_NOSIGNAL);                   
    return train.length;
}

//接受命令
int recv_command(int sockfd, char* parts[]){
    //1.发送第一个火车，发送命令总共有几个部分，即count
    train_t train;
    bzero(&train,sizeof(train));
    recv(sockfd,&train.type,sizeof(train.type),MSG_WAITALL);
    /* if(retv == 0){ */
    /*     return 0; */
    /* } */
    recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);
    recv(sockfd,train.value,train.length,MSG_WAITALL);
    int count = 0;
    memcpy(&count,train.value,train.length);
    //2.发送第二个火车，命令本身
    //3.发送第三个火车，命令的参数（如果有的话）
    for(int i=0;i<count;i++){
        bzero(&train,sizeof(train));
        recv(sockfd,&train.type,sizeof(train.type),MSG_WAITALL);
        recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);
        recv(sockfd,train.value,train.length,MSG_WAITALL);
        // 动态分配内存并复制内容
        parts[i] = (char *)malloc(train.length + 1); // +1 用于字符串结束符
        memcpy(parts[i], train.value, train.length);
        parts[i][train.length] = '\0'; // 添加字符串结束符

        //这样不行，为什么？train的生命周期？
        /* parts[i] = train.value; */
    }
    return count;
}
//发送命令
int send_command(int sockfd, char* parts[], int count){
    //1.发送第一个火车，发送命令总共有几个部分，即count
    train_t train;
    bzero(&train,sizeof(train));
    train.type = CMD_PARTS_COUNT;
    train.length = sizeof(count);
    memcpy(train.value,&count,train.length);
    send(sockfd, &train, sizeof(train.type)+sizeof(train.length)+train.length, MSG_NOSIGNAL);
    //2.发送第二个火车，命令本身
    //3.发送第三个火车，命令的参数（如果有的话）
    for(int i=0;i<count;i++){
        bzero(&train,sizeof(train));
        train.type = (i == 0 ? CMD : CMD_PARAMETER);
        train.length = strlen(parts[i]);
        memcpy(train.value,parts[i],train.length);
        send(sockfd, &train, sizeof(train.type)+sizeof(train.length)+train.length, MSG_NOSIGNAL);
    }
    return count;
}
//发送结果
int send_result(int sockfd,char* result){
    train_t train;
    bzero(&train,sizeof(train));
    train.type = CMD_RESULT;
    train.length = strlen(result) + 1;
    memcpy(train.value,result,train.length);
    send(sockfd,&train,sizeof(train.type)+sizeof(train.length)+train.length,MSG_NOSIGNAL);
    return train.length;
}
//接收结果
int recv_result(int sockfd,char* result){                                                                              
    train_t train;
    bzero(&train,sizeof(train));
    int retv = recv(sockfd,&train.type,sizeof(train.type),MSG_WAITALL);
    if(retv == 0){
        return 0;
    }
    recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);
    recv(sockfd,train.value,train.length,MSG_WAITALL);
    memcpy(result,train.value,train.length);
    return train.length;
}
//客户端向服务端发送文件
int trans_file_to_server(int sockfd, char* file_name){
    //1.发送文件名
    train_t train;
    bzero(&train,sizeof(train));
    train.type = FILE_NAME;
    train.length = strlen(file_name) + 1;
    memcpy(train.value,file_name,train.length);
    send(sockfd,&train,sizeof(train.type)+sizeof(train.length)+train.length,MSG_NOSIGNAL);
    //2.发送文件大小
    int file_fd = open(file_name,O_RDONLY);
    if(file_fd == -1){
        //说明没有这个文件
        return -1;
    }
    struct stat fileStat;
    fstat(file_fd,&fileStat);
    off_t file_size = fileStat.st_size;
    bzero(&train,sizeof(train));
    train.type = FILE_LENGTH;
    train.length = sizeof(file_size);
    memcpy(train.value,&file_size,train.length);
    send(sockfd,&train,sizeof(train.type)+sizeof(train.length)+train.length,MSG_NOSIGNAL);

    //3.发送文件内容
    off_t current_sent_length = 0;
    while(1){
        bzero(&train,sizeof(train));
        train.type = FILE_CONTANT;
        if(file_size - current_sent_length >= 1000){
            train.length = 1000;
        }else{
            train.length = file_size - current_sent_length;
        }        
        if(train.length != 1000){
            printf("%d\n",train.length);                                                                               
        }
        read(file_fd,train.value,train.length);
        send(sockfd,&train,sizeof(train.type)+sizeof(train.length)+train.length,MSG_NOSIGNAL);
        //进度条
        printf("%5.2lf%%\r",current_sent_length*100.0/file_size);
        /* printf("train.value:%s\n",train.value); */
        if(train.length == 0){
            break;
        }
        current_sent_length += train.length;
    }
    printf("100.00%%\n");
    printf("done!\n");

    return file_size;
}
//服务端从客户端接收文件
int recv_file_from_client(int sockfd,char* current_real_path){
    //1.接收文件名
    char file_name[1024] = {0};
    train_t train;
    bzero(&train,sizeof(train));//先清空里面的内容
    recv(sockfd,&train.type,sizeof(train.type),MSG_WAITALL);
    recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);
    recv(sockfd,train.value,train.length,MSG_WAITALL);
    memcpy(file_name,train.value,train.length);
    printf("==%s\n",current_real_path);
    int file_fd = open(current_real_path,O_RDWR|O_CREAT|O_TRUNC,0666);
    if(file_fd == -1){
        return -1;
    }
    /* printf("filename:%s\n",train.value); */
    /* printf("file_fd:%d\n",file_fd); */
    //2.接收文件长度
    bzero(&train,sizeof(train));//先清空里面的内容
    recv(sockfd,&train.type,sizeof(train.type),MSG_WAITALL);
    recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);
    recv(sockfd,train.value,train.length,MSG_WAITALL);
    off_t file_size = 0;
    memcpy(&file_size,train.value,train.length);
    printf("filesize:%lu\n",file_size);
    //3.接收文件内容
    off_t current_recv_length = 0;
    while(1){
        bzero(&train,sizeof(train));
        recv(sockfd,&train.type,sizeof(train.type),MSG_WAITALL);
        recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);
        off_t retv = recv(sockfd,train.value,train.length,MSG_WAITALL);
        printf("train value:%s\n",train.value);
        /* printf("current_recv_length:%lu\n",current_recv_length); */
        //进度条
        /* printf("%5.2lf%%\r",current_recv_length*100.0/file_size); */
        if(retv == 0){
            break;
        }
        current_recv_length+=retv;
        write(file_fd,train.value,train.length);
    }
    printf("100.00%%\n");
    printf("done!\n");
    return file_size;
}
//服务端向客户端发送文件
int trans_file_to_client(int sockfd, char* file_name){
    //1.发送文件名
    train_t train;
    bzero(&train,sizeof(train));
    train.type = FILE_NAME;
    train.length = strlen(file_name) + 1;
    memcpy(train.value,file_name,train.length);
    send(sockfd,&train,sizeof(train.type)+sizeof(train.length)+train.length,MSG_NOSIGNAL);
    //2.发送文件大小
    int file_fd = open(file_name,O_RDONLY);
    if(file_fd == -1){
        //说明没有这个文件
        //向客户端发送一个特殊值
        off_t file_size = 0;
        bzero(&train,sizeof(train));
        train.type = FILE_LENGTH;
        train.length = sizeof(file_size);
        memcpy(train.value,&file_size,train.length);
        send(sockfd,&train,sizeof(train.type)+sizeof(train.length)+train.length,MSG_NOSIGNAL);                                                                                             

        printf("^^^\n");
        return -1;
    }else{
        struct stat fileStat;
        fstat(file_fd,&fileStat);
        off_t file_size = fileStat.st_size;
        bzero(&train,sizeof(train));
        train.type = FILE_LENGTH;
        train.length = sizeof(file_size);
        memcpy(train.value,&file_size,train.length);
        send(sockfd,&train,sizeof(train.type)+sizeof(train.length)+train.length,MSG_NOSIGNAL);
        //3.发送文件内容
        off_t current_sent_length = 0;
        while(1){
            bzero(&train,sizeof(train));
            train.type = FILE_CONTANT;
            if(file_size - current_sent_length >= 1000){
                train.length = 1000;
            }else{
                train.length = file_size - current_sent_length;
            }        
            if(train.length != 1000){
                printf("%d\n",train.length);                                                                               
            }
            read(file_fd,train.value,train.length);
            send(sockfd,&train,sizeof(train.type)+sizeof(train.length)+train.length,MSG_NOSIGNAL);
            //进度条
            /* printf("%5.2lf%%\r",current_sent_length*100.0/file_size); */
            /* printf("train.value:%s\n",train.value); */
            if(train.length == 0){
                break;
            }
            current_sent_length += train.length;
        }
        printf("100.00%%\n");
        printf("done!\n");

        return file_size;
    }

}
//客户端从服务端接收文件
int recv_file_from_server(int sockfd,char* current_real_path){
    //1.接收文件名
    char file_name[1024] = {0};
    train_t train;
    bzero(&train,sizeof(train));//先清空里面的内容
    recv(sockfd,&train.type,sizeof(train.type),MSG_WAITALL);
    recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);
    recv(sockfd,train.value,train.length,MSG_WAITALL);
    memcpy(file_name,train.value,train.length);
    /* printf("filename:%s\n",train.value); */
    /* printf("file_fd:%d\n",file_fd); */
    //2.接收文件长度
    bzero(&train,sizeof(train));//先清空里面的内容
    recv(sockfd,&train.type,sizeof(train.type),MSG_WAITALL);
    recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);
    recv(sockfd,train.value,train.length,MSG_WAITALL);
    off_t file_size = 0;
    memcpy(&file_size,train.value,train.length);
    printf("filesize:%lu\n",file_size);
    if(file_size == 0){
        printf("**\n");
        return -1;
    }else{
        printf("==%s\n",current_real_path);
        int file_fd = open(current_real_path,O_RDWR|O_CREAT|O_TRUNC,0666);
        if(file_fd == -1){
            return -1;
        }
        //3.接收文件内容
        off_t current_recv_length = 0;
        while(1){
            bzero(&train,sizeof(train));
            recv(sockfd,&train.type,sizeof(train.type),MSG_WAITALL);
            recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);
            off_t retv = recv(sockfd,train.value,train.length,MSG_WAITALL);
            printf("train value:%s\n",train.value);
            /* printf("current_recv_length:%lu\n",current_recv_length); */
            //进度条
            printf("%5.2lf%%\r",current_recv_length*100.0/file_size);
            if(retv == 0){
                break;
            }
            current_recv_length+=retv;
            write(file_fd,train.value,train.length);
        }
        printf("100.00%%\n");
        printf("done!\n");
        return file_size;
    }
}
